package net.telesing.tcmc.common;

import org.nutz.dao.*;
import org.nutz.dao.pager.Pager;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.trans.Atom;

import java.util.List;

/**
 * Created by bys on 2015/11/3.
 */
@IocBean
public class BaseDao
{
    @Inject
    private Dao dao;

    public <T extends BaseModel> T insert(T t, long creator)
    {
        t.setCreateUserId(creator);
        return dao.insert(t);
    }

    public <T extends BaseModel> int safeDelete(Class<T> aClass, long id, long updater) throws IllegalAccessException, InstantiationException
    {
        return modifyState(aClass, id, 0, updater);
    }

    public <T extends BaseModel> int modifyState(Class<T> aClass, long id, int state, long updater) throws IllegalAccessException, InstantiationException
    {
        final int[] r = {0};
        final T t = aClass.newInstance();
        t.setId(id);
        FieldFilter.create(aClass, "^state$").run(new Atom()
        {
            public void run()
            {
                r[0] = dao.update(t);
            }
        });
        return r[0];
    }

    public <T extends BaseModel> int delete(Class<T> aClass, long id)
    {
        return dao.delete(aClass, id);
    }

    public <T extends BaseModel> int update(final T t, long updater)
    {
        final int[] r = {0};
        t.setUpdateUserId(updater);
        FieldFilter.create(t.getClass(), null, "^state$", false).run(new Atom()
        {
            public void run()
            {
                r[0] = dao.update(t);
            }
        });
        return r[0];
    }

    public <T extends BaseModel> int count(Class<T> aClass, long id)
    {
        Cnd cnd = Cnd.where("id", "=", id);
        return dao.count(aClass, cnd);
    }

    public <T extends BaseModel> int count(Class<T> aClass, Condition condition)
    {
        return dao.count(aClass, condition);
    }


    public <T extends BaseModel> T fetch(Class<T> aClass, long id)
    {
        Cnd cnd = Cnd.where("id", "=", id);
        return fetch(aClass, cnd);
    }

    public <T extends IdModel> T fetch(Class<T> aClass, Condition condition)
    {
        return dao.fetch(aClass, condition);
    }

    public <T extends BaseModel> T fetchLinks(T t, String s)
    {
        return dao.fetchLinks(t, s);
    }

    public <T extends BaseModel> T fetchLinks(T t, String s, Condition condition)
    {
        return dao.fetchLinks(t, s, condition);
    }

    public <T extends BaseModel, E extends QueryParam> QueryReturn queryPage(Class<T> aClass, E e)
    {
        Pager pager = e.getPager();
        Cnd cnd = e.buildCnd();
        List<T> list = dao.query(aClass, cnd, pager);
        return new QueryReturn<T>(dao.count(aClass, cnd), list,pager.getPageSize());
    }

    public <T> List<T> query(Class<T> aClass, Condition condition)
    {
        return dao.query(aClass, condition);
    }

    public <T extends BaseModel> List<T> query(Class<T> aClass, Condition condition, Pager pager)
    {
        return dao.query(aClass, condition, pager);
    }

    public void execute(Sql... sqls)
    {
        dao.execute(sqls);
    }

    public <T> T insert(T t, long creator)
    {
        return dao.insert(t);
    }

    public <T> int update(final T t)
    {
        final int[] r = {0};
        FieldFilter.create(t.getClass(), null, "^state$", false).run(new Atom()
        {
            public void run()
            {
                r[0] = dao.update(t);
            }
        });
        return r[0];
    }
    /**
     * cnd查询
     * @param aClass
     * @param cnd
     * @return
     * @throws Exception
     */
    public <T> List<T>fetchList(Class<T> aClass, Condition cnd){
        return dao.query(aClass, cnd);
    }

    /**
     * 执行sql语句并获取返回内容
     *
     * @param aClass
     * @param sqlString
     * @param <T>
     * @return
     * @throws Exception
     *
     * Added By Zmt
     */
    public <T> T executeSql(Class<T> aClass, String sqlString) throws Exception
    {
        Sql sql = Sqls.create(sqlString).setCallback(Sqls.callback.entities()).setEntity(dao.getEntity(aClass));
        dao.execute(sql);
        return sql.getObject(aClass);
    }

    /**
     * 执行sql语句并获取返回内容
     *
     * @param sqlString
     * @return
     * @throws Exception
     *
     * Added By Zmt
     */
    public double executeSql(String sqlString)
    {
        Sql sql = Sqls.create(sqlString).setCallback(Sqls.callback.doubleValue());
        dao.execute(sql);
        return sql.getObject(double.class);
    }

}
